#!usr/bin/env python  
# -*- coding:utf-8 _*-
""" 
@author:robot
@file: ct_data_catalogue.py 
@version:
@time: 2022/04/29 
"""
import time

import allure

from TapClientConnector import TapClientConnector
from TapClientCore.T06_Tapdata_feature.v2.TPF05_meta.tpf_meta import TPFMeta
from TapClientCore.T07_CaseTemplate.v2.CT01_datasource.ct_datasource import CTDataSource
from TapUtil.logfunc.logger import logger


class CTDataCataLogue(TPFMeta, CTDataSource):

    @staticmethod
    def common_wait():
        with allure.step('加载数据源后的等待'):
            wait_time = 300
            logger.info(f'加载数据源后的等待: {wait_time}')
            time.sleep(wait_time)

    @staticmethod
    def init_connector(db_info):
        return TapClientConnector(db_info)

    @staticmethod
    def drop_target_table(connector: TapClientConnector):
        logger.info('开始进入目标表删除阶段')
        table = connector.tapclient_connector.CURRENT_TABLE
        if connector.database_type in ['elasticsearch']:
            table = table.lower()
        for raw_table in connector.tapclient_connector.show_tables():
            if table == raw_table:
                with allure.step('目标表删除'):
                    logger.info(f'发现目标要删除的表{table}')
                    drop_operate = connector.tapclient_connector.generate_drop(table)
                    connector.tapclient_connector.exec(drop_operate)
                    logger.info(f'删除目标要同步的表{table}')
                    return
        logger.info(f'没有发现目标要删除的表{table}')

    @staticmethod
    def source_meta_instances_set_check(all_table, meta_list, total):
        """
        :param all_table: 原表通过connector查询的结果
        :param meta_list: 通过接口查询模型的接口
        :param total: 通过接口查询的模型数量
        :return:
        """
        # 比对表与模型
        with allure.step('原表与模型比对'):
            logger.info('模型比对')
            all_table.sort()
            meta_list.sort()
            logger.info(f'source sort table: {all_table}')
            logger.info(f'source sort meta : {meta_list}')

            logger.info(f'raw source count: {len(all_table)}')
            logger.info(f'raw meta total: {total}')
            logger.info(f'raw meta count: {len(meta_list)}')

            with allure.step('获取交集，表-meta的差集'):
                intersection = list(set(all_table) & set(meta_list))
                different = list(set(all_table) - set(meta_list))
                logger.info(f'intersection: {intersection}')
                logger.info(f'intersection count: {len(intersection)}')
            with allure.step('模型数量比对'):
                if len(intersection) != len(all_table):
                    logger.info(f'源 - meta的差集: {different}')
                    logger.info(f'源 - meta的差集数量: {len(different)}')
                    assert False
                else:
                    assert True

    def ct_data_catalogue_base(self, data):
        db_info = data.get('db_info')
        with allure.step('加载数据源，模型比对'):
            # 数据源schema加载
            with allure.step('加载数据源'):
                connection_id = self.DATA_SOURCE_TEMPLATE_CREATE(db_info)
            # 数据源表获取
            with allure.step('连接数据源'):
                _source = self.init_connector(db_info)
            all_table = _source.tapclient_connector.show_tables()
            # 查找数据模型
            self.common_wait()
            with allure.step('查找数据模型'):
                meta_info = self.get_metadataInstances_original_name_by_source_id(connection_id)
                total = meta_info.get('count')
                meta_list = meta_info.get('meta')
            self.source_meta_instances_set_check(all_table, meta_list, total)

    async def delete_meta_by_id_list(self, meta_ids):
        with allure.step('删除数据模型'):
            for meta_id in meta_ids:
                logger.info(f'删除数据模型id{meta_id}')
                self.delete_metadataInstances_by_id(meta_id)

    def ct_delete_catalogue(self, data):
        db_info = data.get('db_info')
        with allure.step('删除模型后，加载数据源，查找模型成功'):
            # 数据源schema加载
            with allure.step('加载数据源'):
                connection_id = self.DATA_SOURCE_TEMPLATE_CREATE(db_info)
            # 查找数据模型
            with allure.step('查找数据模型'):
                meta_info = self.get_metadataInstances_original_name_by_source_id(connection_id)
                meta_ids = meta_info.get('meta_id')
            from TapClientCore.T07_CaseTemplate.v2.CT03_task.data_check.ct_data_check_more_table import async_run
            async_run(self.delete_meta_by_id_list(meta_ids))
            # 数据源schema加载
            with allure.step('加载数据源'):
                connection_id = self.DATA_SOURCE_TEMPLATE_CREATE(db_info)
            # 数据源表获取
            with allure.step('连接数据源'):
                _source = self.init_connector(db_info)
                all_table = _source.tapclient_connector.show_tables()
            # 查找数据模型
            self.common_wait()
            with allure.step('查找数据模型'):
                meta_info = self.get_metadataInstances_original_name_by_source_id(connection_id)
                total = meta_info.get('count')
                meta_list = meta_info.get('meta')
            self.source_meta_instances_set_check(all_table, meta_list, total)

    def ct_delete_meta(self, db_info):
        with allure.step('删除模型后，加载数据源，查找模型成功'):
            # 数据源schema加载
            with allure.step('加载数据源'):
                connection_id = self.DATA_SOURCE_TEMPLATE_CREATE(db_info)
            # 查找数据模型
            with allure.step('查找数据模型'):
                meta_info = self.get_metadataInstances_original_name_by_source_id(connection_id)
                meta_ids = meta_info.get('meta_id')
            from TapClientCore.T07_CaseTemplate.v2.CT03_task.data_check.ct_data_check_more_table import async_run
            async_run(self.delete_meta_by_id_list(meta_ids))

    def ct_add_delete_table_catalogue(self, data):
        table = ''
        db_info = data.get('db_info')
        create_insert_column = data.get('create')
        source_insert_column = data.get('insert')
        try:
            with allure.step('添加表，加载数据源，模型比对'):
                # 数据源表获取
                with allure.step('连接数据源'):
                    _source = self.init_connector(db_info)
                with allure.step('增加表'):
                    logger.info('创建一个新的表')
                    table = _source.tapclient_connector.CURRENT_TABLE
                    create_str = _source.tapclient_connector.generate_create(create_insert_column)
                    insert_str = _source.tapclient_connector.generate_insert(source_insert_column)
                    _source.tapclient_connector.exec(create_str)
                    _source.tapclient_connector.exec(insert_str)
                    all_table = _source.tapclient_connector.show_tables()
                # 数据源schema加载
                with allure.step('加载数据源'):
                    connection_id = self.DATA_SOURCE_TEMPLATE_CREATE(db_info)
                # 查找数据模型
                self.common_wait()
                with allure.step('查找数据模型'):
                    meta_info = self.get_metadataInstances_original_name_by_source_id(connection_id)
                    total = meta_info.get('count')
                    meta_list = meta_info.get('meta')
                self.source_meta_instances_set_check(all_table, meta_list, total)
            with allure.step('删除表，加载数据源，模型比对'):
                # 数据源表获取
                with allure.step('连接数据源'):
                    _source = self.init_connector(db_info)
                with allure.step('删除表'):
                    logger.info('删除新创建的表')
                    drop_str = _source.tapclient_connector.generate_drop(table)
                    _source.tapclient_connector.exec(drop_str)
                    all_table = _source.tapclient_connector.show_tables()
                # 数据源schema加载
                with allure.step('加载数据源'):
                    connection_id = self.DATA_SOURCE_TEMPLATE_CREATE(db_info)
                # 查找数据模型
                self.common_wait()
                with allure.step('查找数据模型'):
                    meta_info = self.get_metadataInstances_original_name_by_source_id(connection_id)
                    total = meta_info.get('count')
                    meta_list = meta_info.get('meta')
                self.source_meta_instances_set_check(all_table, meta_list, total)
        finally:
            with allure.step('连接数据源'):
                _source = self.init_connector(db_info)
                _source.tapclient_connector.CURRENT_TABLE = table
            self.drop_target_table(_source)


if __name__ == '__main__':
    T = CTDataCataLogue()
    from db_info import *

    data = {
        'db_info': Sqlserver.sqlserver_2017_no_cdc
    }
    T.ct_add_delete_table_catalogue(data)
